home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
226-250
/
disk_237
/
cliprint
/
cliprint.asm
< prev
next >
Wrap
Assembly Source File
|
1992-05-06
|
6KB
|
175 lines
;**************************************************************************
; CLIprint.asm by Jeff Glatt
;
; Some people just starting out in assembly always ask about printing to the
; CLI. This program demonstrates how to do that.
;
; An example of printing to the CLI. Must be linked with a startup code that
; sets up a variable, _stdout. This variable is the result of a call to
; dos lib's Output() function, and is the fileHandle of the CLI window from
; where this program was started. If this program was started from WorkBench
; then _stdout will be 0. The provided startup code called StartUp.o has
; been provided for linking with this example. Using BLink,
;
; Blink StartUp.o CLIprint.o small.lib TO CLIPrint
;
; This program does the following:
; 1). Does a straight print of a string using dos lib's Write().
; 2). Does a print of a NULL-terminated string using an included function
; printf. The printf function has the facility to do more than just
; print a string. By including format specifiers in the string, a "new"
; string is created with additional information in it. A format specifier
; is a % character followed immediately by one of the following letters:
; lc - for a character (pass the character on the stack)
; ls - for a string (pass the string's starting address on the stack)
; ld - for a signed decimal representation (pass the 32 bit value on the stack)
; lx - for a hex representation (pass 32 bit value on stack)
; See page B-17 of the Exec ROM Kernal manual for additional options.
; For example, let's say that we have the string
;
;Message dc.b 'The number = %ld',0
;
; printf would not output the '%ld' part of the string to the CLI. Instead,
; it would create a new string where the '%ld' would be replaced by a number
; that you passed on the stack. This number would be represented as an ascii
; string. So, using the above string, we called printf like so:
; lea Message,a0 ;the specifier string goes in a0
; moveq #50,d0 ;let's pass the number 50 as a 32 bit value to printf
; move.l d0,-(sp)
; bsr printf
; addq.l #4,sp ;re-adjust for pushing the 50
; Now printf would print this to the CLI
;
;The number = 50
; 3). Demonstrates calls to printf with imbedded specifiers.
;from StartUp.o
XREF _stdout,_DOSBase,_SysBase
;from small.lib
XREF _LVOWrite,_LVORawDoFmt
SECTION printfdata,DATA
Message1Len equ 32 ;don't count terminating NULL
Message1 dc.b 'This is a print using Write().',13,10,0
Message2 dc.b 'This is a print using printf().',13,10,0
Format1 dc.b 'The number passed to printf = %ld',13,10,0
Format2 dc.b 'The string passed to printf is "%ls".',13,10,0
StringInside dc.b 'Hello',0
Format3 dc.b 'The number is %ld, and string = %ls',13,10,0
Format4 dc.b 'The number in hex = $%lx',13,10,0
FinalMsg dc.b 'Understand, Bozo?',13,10,0
SECTION printfcode,CODE
XDEF _main ;the first routine you want executed must be called _main.
_main:
;---Output a straight string via Write()
lea Message1,a0
move.l a0,d2
moveq #Message1Len,d3
move.l _stdout,d1
movea.l _DOSBase,a6
jsr _LVOWrite(a6)
;---Output a straight string via printf
lea Message2,a0
bsr printf
;---Output a number inside of the string specifier via printf
lea Format1,a0
moveq #50,d0
move.l d0,-(sp)
bsr printf
addq.l #4,sp
;---Output that number again (but use the hex specifier)
lea Format4,a0
moveq #50,d0
move.l d0,-(sp)
bsr printf
addq.l #4,sp
;---Output a string inside of the string specifier via printf
lea StringInside,a1
move.l a1,-(sp)
lea Format2,a0
bsr printf
addq.l #4,sp
;---Output a string and number inside of the string specifier
; The order to push the args is reverse to the order that they are inserted
; into the string (i.e. my %ld came before my %s, so I push StringInside
; first then the number 50)
lea StringInside,a1
move.l a1,-(sp)
moveq #50,d0
move.l d0,-(sp)
lea Format3,a0
bsr printf
addq.l #8,sp ;note: re-adjust for 2 LONG pushes
;---One last insult
lea FinalMsg,a0
bsr printf
;---Get out of this program
rts
;=======================================================================
; Pass string specifier in a0, and any args on the stack.
XDEF printf
printf:
;---If we're from WorkBench, _stdout = 0. Get out of here.
move.l _stdout,d0
beq.s noPF
;---Get the address of where we pushed any args in a1
lea 4(sp),a1
;---Save some regs
movem.l d2/d3/a2/a3/a4/a6,-(sp)
;---Save the address of stdout
movea.l d0,a4
;---Get a buffer on the stack to create a "new" string
; Now we call Exec's RawDoFmt. It does all the work of formatting
; the new string. It needs the address of a function we create. This
; function just throws a char into our "new" buffer. Exec calls this
; for every "new" character it creates.
moveq #126,d0
suba.l d0,sp
lea StoreChar,a2
movea.l sp,a3
;address of args in a1
movea.l _SysBase,a6
jsr _LVORawDoFmt(a6)
;---Count how many chars are in the string (it will be NULL-terminated)
moveq #126-1,d1
move.l a3,d2 ;the start of our "new" string
cntC move.b (a3)+,d0
Dbeq d1,cntC(pc)
;---Determine # of chars
subq.l #1,a3
move.l a3,d3
sub.l d2,d3
beq.s char0 ;if 0 chars, don't print anything
;---Print out to _stdout (which will be the CLI window unless the user
; redirected output on the command line using the '>')
move.l a4,d1
;address of string in d2
movea.l _DOSBase,a6
jsr _LVOWrite(a6)
;---Get rid of our "new" buffer
char0 moveq #126,d0
adda.l d0,sp
;---Restore regs
movem.l (sp)+,d2/d3/a2/a3/a4/a6
noPF rts
;Exec passes a "new" character (in d0) to be stored in our "new" buffer
;(address in a3).
StoreChar move.b d0,(a3)+
rts